package com.bf.electroplating.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bf.electroplating.pojo.dto.MessageDTO;
import com.bf.electroplating.pojo.entity.MessageLog;
import com.bf.electroplating.pojo.vo.equipment.ClientVo;
import com.bf.electroplating.pojo.vo.equipment.ConnectedClientVo;
import com.bf.electroplating.service.MessageLogService;
import com.bf.electroplating.service.compoent.HJ212ServiceManager;
import com.bf.electroplating.service.compoent.HJ212Server;
import com.bf.electroplating.service.compoent.HJ212TestClient;
import com.bf.electroplating.pojo.vo.ResultVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * HJ212服务管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/hj212")
@Tag(name = "HJ212服务管理", description = "HJ212协议服务器管理接口")
public class HJ212Controller {
    
    @Autowired
    private HJ212ServiceManager hj212ServiceManager;
    
    @Autowired
    private HJ212Server hj212Server;

    @Resource
    private MessageLogService messageLogService;
    
    @Autowired
    private HJ212TestClient hj212TestClient;
    
    @PostMapping("/start")
    @Operation(summary = "启动HJ212服务", description = "启动HJ212协议服务器")
    public ResultVO<String> startService() {
        try {
            hj212ServiceManager.startService();
            return ResultVO.ok("HJ212服务启动成功");
        } catch (Exception e) {
            log.error("启动HJ212服务失败", e);
            return ResultVO.fail("启动HJ212服务失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/stop")
    @Operation(summary = "停止HJ212服务", description = "停止HJ212协议服务器")
    public ResultVO<String> stopService() {
        try {
            hj212ServiceManager.stopService();
            return ResultVO.ok("HJ212服务已停止");
        } catch (Exception e) {
            log.error("停止HJ212服务失败", e);
            return ResultVO.fail("停止HJ212服务失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/restart")
    @Operation(summary = "重启HJ212服务", description = "重启HJ212协议服务器")
    public ResultVO<String> restartService() {
        try {
            hj212ServiceManager.restartService();
            return ResultVO.ok("HJ212服务重启成功");
        } catch (Exception e) {
            log.error("重启HJ212服务失败", e);
            return ResultVO.fail("重启HJ212服务失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/status")
    @Operation(summary = "查询服务状态", description = "查询HJ212协议服务器运行状态")
    public ResultVO<Boolean> getServiceStatus() {
        try {
            boolean isRunning = hj212ServiceManager.isServiceRunning();
            return ResultVO.ok(isRunning);
        } catch (Exception e) {
            log.error("查询服务状态失败", e);
            return ResultVO.fail("查询服务状态失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/clients")
    @Operation(summary = "获取连接客户端列表", description = "获取当前连接到HJ212服务器的所有客户端信息")
    public ResultVO< ConnectedClientVo > getConnectedClients() {
        try {
            ConcurrentHashMap<String, String> clients = hj212Server.getConnectedClients();
            int clientCount = hj212Server.getConnectedClientsCount();
            
            // 将客户端信息转换为ClientVo集合
            List<ClientVo> clientVoList = clients.entrySet().stream()
                    .map(entry -> {
                        ClientVo clientVo = new ClientVo();
                        clientVo.setClientId(entry.getKey());
                        String mn = hj212Server.getClientIdByMn ( entry.getKey () );
                        clientVo.setMn ( mn );
                        clientVo.setAddress (entry.getValue());
//                        clientVo.setIsConnect ( checkIsAlive( mn ) );
                        return clientVo;
                    })
                    .toList();
            ConnectedClientVo vo = new ConnectedClientVo ();

            vo.setCount ( clientCount );
            vo.setClientVo ( clientVoList );


            return ResultVO.ok( vo );
        } catch (Exception e) {
            log.error("获取客户端列表失败", e);
            return ResultVO.fail("获取客户端列表失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/clients/count")
    @Operation(summary = "获取连接数", description = "获取当前连接到HJ212服务器的客户端数量")
    public ResultVO<Integer> getClientCount() {
        try {
            int count = hj212Server.getConnectedClientsCount();
            return ResultVO.ok(count);
        } catch (Exception e) {
            log.error("获取连接数失败", e);
            return ResultVO.fail("获取连接数失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/clients/send")
    @Operation(summary = "向指定客户端发送消息", description = "向指定的HJ212客户端发送消息")
    public ResultVO<String> sendMessageToClient( @Validated @RequestBody MessageDTO dto ) {
        try {
            boolean success = hj212Server.sendMessageToClient(dto.getClientId (), dto.getMessage ());
            if (success) {
                return ResultVO.ok("消息发送成功");
            } else {
                return ResultVO.fail("消息发送失败，客户端可能不存在或已断开连接");
            }
        } catch (Exception e) {
            log.error("发送消息失败", e);
            return ResultVO.fail("发送消息失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/clients/broadcast")
    @Operation(summary = "广播消息", description = "向所有连接的HJ212客户端广播消息")
    public ResultVO<String> broadcastMessage(
            @Parameter(description = "要广播的消息") @RequestParam String message) {
        try {
            int successCount = hj212Server.broadcastMessage(message);
            return ResultVO.ok("广播完成，成功发送给 " + successCount + " 个客户端");
        } catch (Exception e) {
            log.error("广播消息失败", e);
            return ResultVO.fail("广播消息失败: " + e.getMessage());
        }
    }
    
    @DeleteMapping("/clients/{clientId}")
    @Operation(summary = "断开客户端连接", description = "断开指定HJ212客户端的连接")
    public ResultVO<String> disconnectClient(
            @Parameter(description = "客户端ID") @PathVariable String clientId) {
        try {
            boolean success = hj212Server.disconnectClient(clientId);
            if (success) {
                return ResultVO.ok("客户端连接已断开");
            } else {
                return ResultVO.fail("断开连接失败，客户端可能不存在");
            }
        } catch (Exception e) {
            log.error("断开客户端连接失败", e);
            return ResultVO.fail("断开客户端连接失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/clients/{clientId}/status")
    @Operation(summary = "检查客户端连接状态", description = "检查指定HJ212客户端是否已连接")
    public ResultVO<Boolean> isClientConnected(
            @Parameter(description = "客户端ID") @PathVariable String clientId) {
        try {
            boolean isConnected = hj212Server.isClientConnected(clientId);
            return ResultVO.ok(isConnected);
        } catch (Exception e) {
            log.error("检查客户端连接状态失败", e);
            return ResultVO.fail("检查客户端连接状态失败: " + e.getMessage());
        }
    }

    private Boolean checkIsAlive( String mn ){
        if ( StringUtils.isBlank ( mn ) ){
            return null;
        }
        LambdaQueryWrapper < MessageLog > wrapper = new LambdaQueryWrapper <> ();
        wrapper.eq ( MessageLog::getMn, mn )
                .ge ( MessageLog::getCreateTime, new Date ( System.currentTimeMillis () - 5 * 60 * 1000 ) );
        List < MessageLog > messageLogs = messageLogService.list ( wrapper );
        return ! CollectionUtils.isEmpty ( messageLogs );
    }

    @PostMapping("/simulate/client/request")
    @Operation(summary = "模拟客户端请求", description = "模拟客户端向HJ212服务器发送请求")
    public ResultVO<String> simulateClientRequest(
            @Parameter(description = "请求类型：standard(标准数据包), realtime(实时数据), custom(自定义数据)") 
            @RequestParam(defaultValue = "standard") String requestType,
            @Parameter(description = "污染物代码，仅在realtime类型时使用") 
            @RequestParam(required = false) String pollutantCode,
            @Parameter(description = "数值，仅在realtime类型时使用") 
            @RequestParam(required = false) String value,
            @Parameter(description = "自定义数据包内容，仅在custom类型时使用") 
            @RequestParam(required = false) String customData,
            @Parameter(description = "服务器地址") 
            @RequestParam(defaultValue = "localhost") String host,
            @Parameter(description = "服务器端口") 
            @RequestParam(defaultValue = "8103") int port) {
        try {
            String response = null;
            
            switch (requestType.toLowerCase()) {
                case "standard":
                    response = hj212TestClient.sendStandardPacket(host, port);
                    break;
                case "realtime":
                    if (StringUtils.isBlank(pollutantCode) || StringUtils.isBlank(value)) {
                        return ResultVO.fail("实时数据请求需要提供污染物代码和数值");
                    }
                    response = hj212TestClient.sendRealTimeData(host, port, pollutantCode, value);
                    break;
                case "custom":
                    if (StringUtils.isBlank(customData)) {
                        return ResultVO.fail("自定义数据请求需要提供数据包内容");
                    }
                    response = hj212TestClient.sendTestPacket(host, port, customData);
                    break;
                default:
                    return ResultVO.fail("不支持的请求类型: " + requestType);
            }
            
            if (response != null) {
                return ResultVO.ok("模拟客户端请求成功，服务器响应: " + response);
            } else {
                return ResultVO.fail("模拟客户端请求失败，未收到服务器响应");
            }
            
        } catch (Exception e) {
            log.error("模拟客户端请求失败", e);
            return ResultVO.fail("模拟客户端请求失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/simulate/client/connect")
    @Operation(summary = "模拟客户端连接", description = "模拟客户端连接到HJ212服务器并保持连接")
    public ResultVO<String> simulateClientConnect(
            @Parameter(description = "服务器地址") 
            @RequestParam(defaultValue = "localhost") String host,
            @Parameter(description = "服务器端口") 
            @RequestParam(defaultValue = "8103") int port) {
        try {
            boolean success = hj212TestClient.connectToServer(host, port);
            if (success) {
                return ResultVO.ok("模拟客户端连接成功");
            } else {
                return ResultVO.fail("模拟客户端连接失败");
            }
        } catch (Exception e) {
            log.error("模拟客户端连接失败", e);
            return ResultVO.fail("模拟客户端连接失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/simulate/client/disconnect")
    @Operation(summary = "模拟客户端断开连接", description = "模拟客户端断开与HJ212服务器的连接")
    public ResultVO<String> simulateClientDisconnect() {
        try {
            hj212TestClient.disconnectFromServer();
            return ResultVO.ok("模拟客户端已断开连接");
        } catch (Exception e) {
            log.error("模拟客户端断开连接失败", e);
            return ResultVO.fail("模拟客户端断开连接失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/simulate/client/status")
    @Operation(summary = "查询模拟客户端连接状态", description = "查询模拟客户端是否已连接到HJ212服务器")
    public ResultVO<Boolean> getSimulateClientStatus() {
        try {
            boolean isConnected = hj212TestClient.isConnected();
            return ResultVO.ok(isConnected);
        } catch (Exception e) {
            log.error("查询模拟客户端状态失败", e);
            return ResultVO.fail("查询模拟客户端状态失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/simulate/client/send")
    @Operation(summary = "模拟客户端发送数据", description = "模拟已连接的客户端向服务器发送数据")
    public ResultVO<String> simulateClientSend(
            @Parameter(description = "请求类型：standard(标准数据包), realtime(实时数据), custom(自定义数据)") 
            @RequestParam(defaultValue = "standard") String requestType,
            @Parameter(description = "污染物代码，仅在realtime类型时使用") 
            @RequestParam(required = false) String pollutantCode,
            @Parameter(description = "数值，仅在realtime类型时使用") 
            @RequestParam(required = false) String value,
            @Parameter(description = "自定义数据包内容，仅在custom类型时使用") 
            @RequestParam(required = false) String customData) {
        try {
            if (!hj212TestClient.isConnected()) {
                return ResultVO.fail("模拟客户端未连接，请先调用连接接口");
            }
            
            boolean success = false;
            
            switch (requestType.toLowerCase()) {
                case "standard":
                    success = hj212TestClient.sendStandardPacket();
                    break;
                case "realtime":
                    if (StringUtils.isBlank(pollutantCode) || StringUtils.isBlank(value)) {
                        return ResultVO.fail("实时数据请求需要提供污染物代码和数值");
                    }
                    success = hj212TestClient.sendRealTimeData(pollutantCode, value);
                    break;
                case "custom":
                    if (StringUtils.isBlank(customData)) {
                        return ResultVO.fail("自定义数据请求需要提供数据包内容");
                    }
                    success = hj212TestClient.sendTestPacket(customData);
                    break;
                default:
                    return ResultVO.fail("不支持的请求类型: " + requestType);
            }
            
            if (success) {
                return ResultVO.ok("模拟客户端发送数据成功");
            } else {
                return ResultVO.fail("模拟客户端发送数据失败");
            }
            
        } catch (Exception e) {
            log.error("模拟客户端发送数据失败", e);
            return ResultVO.fail("模拟客户端发送数据失败: " + e.getMessage());
        }
    }
} 